package com.ybg.bookmanages.services.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ybg.bookcommons.dto.BorrowBookDTO;
import com.ybg.bookmanages.commons.UploadImgUtil;
import com.ybg.bookmanages.mapper.BookinfosMapper;
import com.ybg.bookmanages.mapper.BorrowBooksMapper;
import com.ybg.bookmanages.mapper.DemageBookMapper;
import com.ybg.bookmanages.mapper.UserinfosMapper;
import com.ybg.bookmanages.module.entity.Bookinfos;
import com.ybg.bookmanages.module.entity.BorrowBooks;
import com.ybg.bookmanages.module.entity.DemageBooks;
import com.ybg.bookmanages.module.entity.userinfos;
import com.ybg.bookmanages.module.vo.BookinfosVO;
import com.ybg.bookmanages.services.BookinfosService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.util.Date;

@Service
public class BookinfosServiceImpl extends ServiceImpl<BookinfosMapper, Bookinfos> implements BookinfosService {
    private final Logger log = LoggerFactory.getLogger(BookinfosServiceImpl.class);
    // 从配置文件中获取上传目录配置
    @Value("${file.upload_dir}")
    private String uploadDir;

    @Resource
    private UploadImgUtil uploadImgUtil;
    @Resource
    private DemageBookMapper demageBookMapper;
    @Resource
    private BorrowBooksMapper borrowBooksMapper;
    @Resource
    private UserinfosMapper userinfosMapper;

    @Transactional
    @Override
    public boolean addBook(BookinfosVO bvo, MultipartFile file) {
        try {
            // 检查目录是否存在，如果不存在则创建
            Path path = Paths.get(uploadDir);
            if (!Files.exists(path)) {
                Files.createDirectory(path);
            }

            // 只有在文件不为空时才进行文件处理
            if (file != null && !file.isEmpty()) {
                //将图片存储到临时文件目录
                String serverTmpImgPath = path.toAbsolutePath() + File.separator + file.getOriginalFilename();
                File tmpImg = new File(serverTmpImgPath);
                file.transferTo(tmpImg);
                //将临时文件上传fastdfs
                String returnPath = uploadImgUtil.upload(serverTmpImgPath);
                //System.out.println(returnPath);
                //将服务器返回的文件路径保存到MYSQL数据库中
                Bookinfos book = new Bookinfos();
                BeanUtils.copyProperties(bvo, book);
                book.setBookimage(returnPath);
                book.setDeleted(0);
                save(book);
                //删除临时文件
                tmpImg.delete();
                return true;
            } else {
                return false;
            }

        } catch (IOException e) {
            log.error("新增图书失败：" + e.getMessage());
            return false;
        }
    }

    @Override
    public boolean damageBook(String isbn, String demagereason) {
        try {
            //1.按照isbn查询图书编号
            QueryWrapper<Bookinfos> query = new QueryWrapper<>();
            query.eq("isbn", isbn);
            Bookinfos book = this.getOne(query);
            //2.将破损图书信息存放到破损表中
            DemageBooks demageBook = DemageBooks.builder()
                    .bookid(book.getBookid())
                    .demagedate(new Date())
                    .demagereason(demagereason)
                    .build();
            demageBookMapper.insert(demageBook);
            //3.计算在库图书是否已经破损
            QueryWrapper<DemageBooks> demageQuery = new QueryWrapper<>();
            demageQuery.eq("bookid", book.getBookid());
            Long demageNum = demageBookMapper.selectCount(demageQuery);
            if (book.getStore().longValue() - demageNum.longValue() <= 0) {
                //3.1如果都已经破损则图书下架
                this.removeById(book.getBookid());
            }
            return true;
        } catch (Exception e) {
            log.error("图书破损处理失败：" + e.getMessage());
            return false;
        }

    }

    @Override
    public boolean borrowBook(String isbn, String carid) {
        //1.查询该图书当前库存
        Long store = this.getBaseMapper().selectBookCurrentStore(isbn);
        if (store.longValue() > 0) {
            //2.如果库存足够则向借阅表中插入数据
            LambdaQueryWrapper<Bookinfos> bookQuery = new LambdaQueryWrapper<>();
            bookQuery.eq(Bookinfos::getIsbn, isbn);
            Bookinfos book = this.getOne(bookQuery);
            LambdaQueryWrapper<userinfos> userQuery = new LambdaQueryWrapper<>();
            userQuery.eq(userinfos::getCarid, carid);
            userinfos us = userinfosMapper.selectOne(userQuery);

            LocalDate now = LocalDate.now();

            BorrowBooks borrow = BorrowBooks.builder().bookid(book.getBookid())
                    .userid(us.getUserid())
                    .borrowdate(Date.from(now.atStartOfDay(ZoneId.systemDefault()).toInstant()))
                    .returndate(Date.from(now.plusDays(10).atStartOfDay(ZoneId.systemDefault()).toInstant()))
                    .build();
            int res = borrowBooksMapper.insert(borrow);
            System.out.println(borrow);
            if (res == 0) {
                return false;
            } else {
                return true;
            }
        } else {
            //3.如果库存不足则返回false
            return false;
        }
    }

    @Override
public BorrowBookDTO backBook(String isbn, String carid) {
    try {
        //1.根据图书isbn和carid查询bookid和userid
        LambdaQueryWrapper<Bookinfos> bookQuery = new LambdaQueryWrapper<>();
        bookQuery.eq(Bookinfos::getIsbn, isbn);
        Bookinfos book = this.getOne(bookQuery);

        if (book == null) {
            log.error("未找到ISBN为 {} 的图书", isbn);
            return null;
        }

        LambdaQueryWrapper<com.ybg.bookmanages.module.entity.userinfos> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(com.ybg.bookmanages.module.entity.userinfos::getCarid, carid);
        com.ybg.bookmanages.module.entity.userinfos us = userinfosMapper.selectOne(userQuery);

        if (us == null) {
            log.error("未找到身份证号为 {} 的用户", carid);
            return null;
        }

        //2.根据bookid和userid查询借阅记录
        LambdaQueryWrapper<BorrowBooks> borrowQuery = new LambdaQueryWrapper<>();
        borrowQuery.eq(BorrowBooks::getBookid, book.getBookid())
                  .eq(BorrowBooks::getUserid, us.getUserid())
                  .isNull(BorrowBooks::getRealbackdate); // 只查询未归还的记录
        BorrowBooks recode = borrowBooksMapper.selectOne(borrowQuery);

        // 检查是否找到借阅记录
        if (recode == null) {
            log.error("未找到用户 {} 借阅图书 {} 的记录", carid, isbn);
            return null;
        }

        //3.计算用户借阅是否超逾期 如逾期则计算罚款
        LocalDateTime now = LocalDateTime.now();
        LocalDate returnDate = LocalDate.ofInstant(recode.getReturndate().toInstant(), ZoneId.systemDefault());
        LocalDate today = LocalDate.now();

        // 计算逾期天数
        long days = java.time.temporal.ChronoUnit.DAYS.between(returnDate, today);

        // 更新实际归还时间
        recode.setRealbackdate(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));

        // 如果逾期天数大于0，则计算罚款
        if (days <= 0) {
            recode.setOverdue(0.0);
        } else {
            recode.setOverdue(days * 0.1); // 每天0.1元罚款
        }

        //4.更新借阅信息
        int res = borrowBooksMapper.updateById(recode);

        //将信息存放到BorrowBookDTO中并返回
        BorrowBookDTO bbdto = BorrowBookDTO.builder()
                .bookname(book.getBookname())
                .borrowdate(recode.getBorrowdate())
                .returndate(recode.getReturndate())
                .realbackdate(recode.getRealbackdate())
                .overdue(recode.getOverdue())
                .build();

        return bbdto;

    } catch (Exception e) {
        log.error("图书归还处理失败：" + e.getMessage());
        return null;
    }
}


}
